package com.pf.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;

/**
 * jwt
 */
@Slf4j
public class JwtUtils {

    /**
     * jwt加密的密钥
     */
    private static final String JWT_SECRET = "myJwtSecret";

    /**
     * 有效期两个小时
     */
    private static final int EXPIRE_TIME = 2 * 60 * 60 * 1000;

    /**
     * 用户appId
     */
    private static final String APP_ID_KEY = "appId";

    /**
     * 生成jwt
     *
     * @param appId
     * @return
     */
    public static String generateToken(String appId) {
        try {
            return JWT.create()
                    // jwt 默认的header就是 {"alg":"HS256","typ":"JWT"} ，如果sign使用的是 HMAC256 ，可以不用添加这行
                    //.withHeader(ImmutableMap.of("alg", "HS256", "typ", "JWT"))
                    .withClaim(APP_ID_KEY, appId)
                    .withIssuedAt(new Date())
                    .withExpiresAt(new Date(System.currentTimeMillis() + EXPIRE_TIME))
                    .sign(Algorithm.HMAC256(JWT_SECRET));
        } catch (Exception e) {
            log.info(">>>>> generateToken error", e);
        }
        return "";
    }

    /**
     * 从token中获取对应的key值
     *
     * @param token
     * @param claimsKey
     * @return
     */
    private static Claim getClaimsFromToken(String token, String claimsKey) {
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(JWT_SECRET)).build();
            DecodedJWT jwt = verifier.verify(token);
            Claim claim = jwt.getClaim(claimsKey);
            return claim;
        } catch (Exception e) {
            log.info(">>>>> getClaimsFromToken error", e);
        }
        return null;
    }

    /**
     * 获取token的过期时间
     *
     * @param token
     * @return
     */
    public static Date getExpiredDateFromToken(String token) {
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(JWT_SECRET)).build();
            DecodedJWT jwt = verifier.verify(token);
            return jwt.getExpiresAt();
        } catch (Exception e) {
            log.info(">>>>> getExpiredDateFromToken error!", e);
            return null;
        }
    }

    /**
     * 判断token是否过期
     *
     * @param token
     * @return true：已过期；false：未过期
     */
    private static boolean isTokenExpiration(String token) {
        Date expiredDate = getExpiredDateFromToken(token);
        return expiredDate.before(new Date());
    }

    /**
     * 获取用户id
     *
     * @param token
     * @return
     */
    public static String getAppId(String token) {
        Claim claim = getClaimsFromToken(token, APP_ID_KEY);
        if (claim != null) {
            return claim.asString();
        } else {
            return null;
        }

    }

    /**
     * 校验token是否合法
     * <p>
     * 校验规则：
     * 1.传入用户id和token中不一致
     * 2.token已过期
     *
     * @param token
     * @param appId
     * @return true 合法  false 不合法
     */
    public static boolean validateToken(String token, String appId) {
        String appIdFrom = getAppId(token);
        return appId.equals(appIdFrom) && !isTokenExpiration(token);
    }
}
